package com.trinity.web.controller.payment;

import com.alibaba.fastjson2.JSON;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.trinity.campus.domain.CampusStudents;
import com.trinity.campus.domain.CampusUserStudent;
import com.trinity.campus.dto.StudentOrderVO;
import com.trinity.campus.service.ICampusStudentsService;
import com.trinity.common.annotation.Log;
import com.trinity.common.constant.HttpStatus;
import com.trinity.common.core.controller.BaseController;
import com.trinity.common.core.domain.AjaxResult;
import com.trinity.common.core.domain.entity.SysDept;
import com.trinity.common.core.domain.entity.WxUser;
import com.trinity.common.core.page.TableDataInfo;
import com.trinity.common.enums.BusinessType;
import com.trinity.common.exception.ServiceException;
import com.trinity.common.utils.bean.BeanUtils;
import com.trinity.order.refund.domain.XcRefundOrder;
import com.trinity.order.refund.service.IXcRefundOrderService;
import com.trinity.orders.constant.OrderConstants;
import com.trinity.orders.domain.XcOrders;
import com.trinity.orders.domain.XcOrdersGoods;
import com.trinity.orders.domain.XcPayRecord;
import com.trinity.orders.dto.XcOrdersVO;
import com.trinity.orders.service.IXcOrdersService;
import com.trinity.orders.service.IXcPayRecordService;
import com.trinity.payment.domain.ListStudentBookDao;
import com.trinity.service.impl.WxUserServiceImpl;
import com.trinity.specialpay.dto.QueryActivityResultDto;
import com.trinity.system.service.ISysConfigService;
import com.trinity.system.service.ISysDeptService;
import com.trinity.uniquefees.domain.UfBookList;
import com.trinity.uniquefees.domain.bo.UfStudentBook;
import com.trinity.uniquefees.service.IUfBookListService;
import com.trinity.uniquefees.service.IUfCourseBookService;
import com.trinity.uniquefees.service.IUfStudentBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 缴费名单Controller
 *
 * @author trinity
 * @date 2023-11-21
 */
@Slf4j
@RestController
@RequestMapping("/payment/pay-list")
public class PaymentController extends BaseController {

    @Resource
    private ICampusStudentsService campusStudentsService;

    @Resource
    private IUfStudentBookService studentBookService;
    @Resource
    private IUfCourseBookService iUfCourseBookService;

    @Resource
    private IXcPayRecordService payRecordService;

    @Resource
    private IXcOrdersService ordersService;

    @Resource
    private ISysDeptService sysDeptService;

    @Resource
    private WxUserServiceImpl wxUserService;

    @Resource
    private IXcRefundOrderService refundOrderService;

    @Resource
    private IUfBookListService bookListService;

    @Resource
    private ISysConfigService configService;

    /**
     * id 系统订单号
     * amount  核销金额
     *
     * @param data data
     */
    @RequestMapping(value = "/manual/hx", method = {RequestMethod.POST})
    public AjaxResult manualConfirmation(@RequestBody Map<String, Object> data) {
        try {
            String orderId = (String) data.get("id");
            String amount = (String) data.get("amount");
            String remark = (String) data.get("remark");
            String currency = "CNY";
            ordersService.manualConf(orderId, amount, currency,remark);
            return success("核销成功！");
        } catch (Exception e) {
            return error("核销失败：" + e.getMessage());
        }


    }

    /**
     * 查询缴费名单列表
     */
    @Deprecated
    @GetMapping("/list")
    public TableDataInfo listAll(UfStudentBook queryUfStudentBookParams) {
        startPage();
        List<ListStudentBookDao> listStudentBookDaos = studentBookService.selectPaymentListDto(queryUfStudentBookParams);
        return getDataTable(listStudentBookDaos);
    }

    /**
     * -- 未使用
     * 查询订单信息列表
     */
    @Deprecated
    @GetMapping("/orders2")
    public TableDataInfo studentOrder(XcOrders xcOrders) {
        startPage();
        Long userId = getUserId();
        CampusUserStudent bindStudent = campusStudentsService.getBindStudent(userId);
        if (bindStudent == null || bindStudent.getCampusStudent() == null) {
            throw new ServiceException("请先绑定学号！");
        }
        xcOrders.setStudentId(String.valueOf(bindStudent.getCampusStudent().getStudentId()));
        List<XcOrders> list = ordersService.selectXcOrdersList(xcOrders);
        List<QueryActivityResultDto> resultDtos = new ArrayList<>(list.size());
        for (XcOrders order : list) {
            QueryActivityResultDto vo = new QueryActivityResultDto();
            vo.setId(order.getId());
            vo.setName(order.getOrderName());
            vo.setAmount(order.getTotalPrice());
            vo.setExplain(order.getOrderDescrip());
            vo.setStartTime(order.getCreateTime());
            if ("NOTPAY".equals(order.getStatus())) {
                //未支付
                vo.setPay(false);
            }
            if ("SUCCESS".equals(order.getStatus())) {
                //已
                vo.setPayTime(order.getUpdateTime());
                vo.setPay(true);
            }
            resultDtos.add(vo);
        }

        return getDataTable(resultDtos);
    }

    /**
     * 查询订单信息列表
     */
    @GetMapping("/orders")
    public TableDataInfo orderList(XcOrders xcOrders) {
        startPage();
        Long userId = getUserId();
        CampusUserStudent bindStudent = campusStudentsService.getBindStudent(userId);
        if (bindStudent == null || bindStudent.getCampusStudent() == null) {
            TableDataInfo rspData = new TableDataInfo();
            rspData.setCode(HttpStatus.ERROR);
            rspData.setMsg("请先绑定学号！");
            return rspData;
        }
        xcOrders.setStudentId(String.valueOf(bindStudent.getCampusStudent().getStudentId()));
        xcOrders.setOther2("2"); //缴费项目为进行中状态的订单
        List<XcOrders> list = ordersService.selectXcOrdersList(xcOrders);
        List<QueryActivityResultDto> resultDtos = new ArrayList<>(list.size());
        for (XcOrders order : list) {
            QueryActivityResultDto vo = new QueryActivityResultDto();
            vo.setId(order.getId());
            vo.setName(order.getOrderName());
            vo.setAmount(order.getTotalPrice());
            vo.setExplain(order.getOrderDescrip());
            vo.setStartTime(order.getCreateTime());
            if (OrderConstants.OrderState.NOTPAY.equals(order.getStatus())) {
                //未支付
                vo.setPay(false);
            }
            if (OrderConstants.TradeState.SUCCESS.equals(order.getStatus())) {
                //已
                vo.setPayTime(order.getUpdateTime());
                vo.setPay(true);
            }
            if (OrderConstants.TradeState.REFUND.equals(order.getStatus())) {
                //已退款 也是支付
                vo.setPayTime(order.getUpdateTime());
                vo.setPay(true);
            }
            resultDtos.add(vo);
        }

        return getDataTable(resultDtos);
    }


    /**
     * 微信支付-申请退款
     *
     * @param refundOrder 支付订单
     * @return re
     */

    @Log(title = "微信支付-申请退款", businessType = BusinessType.UPDATE)
    @PostMapping("/refund")
    public AjaxResult refund(@RequestBody Map<String, Object> refundOrder) {
        log.info("微信支付-申请退款 =======>");
        return ordersService.refundOrder(refundOrder);
    }

    @Log(title = "小程序支付完成调用", businessType = BusinessType.UPDATE)
    @PostMapping("/order/app/notify")
    public AjaxResult pollingOrder(@RequestBody Map<String, Object> param) {
        log.info("小程序支付完成调用 =======> {}", param.toString());
        String orderNo = (String) param.get("orderNo");
        String payNo = (String) param.get("payNo");
        String tradeState = (String) param.get("TradeState");
        return ordersService.pollingOrder(orderNo, payNo, tradeState);
//        return success();
    }

    /**
     * 取消订单
     */
    @PostMapping(value = "/cancel/{id}")
    public AjaxResult cancel(@PathVariable("id") String id) {
        log.info("取消订单 ==> ");
        try {
            ordersService.cancelOrder(id);
            return success("订单已取消！");
        } catch (WxPayException e) {
//            if ("ORDERPAID".equals()) {
//            }
            return error(e.getErrCode() + ":" + e.getCustomErrorMsg());
        }
    }

    /**
     * 订单详情
     */
    @GetMapping(value = "/orders/{id}")
    public AjaxResult getOderInfo(@PathVariable("id") String id) {
        Map<String, Object> orderMap = new HashMap<>();
        XcOrders order = ordersService.selectXcOrdersById(id);
        if (order == null) {
            throw new ServiceException("订单不存在");
        }
        // 学校 学院 专业 班级
        SysDept dept = sysDeptService.selectDeptById(Long.valueOf(order.getDeptId()));
        String ancestors = dept.getAncestors();
        Long[] array = Arrays.stream(ancestors.split(","))
                .map(Long::parseLong)
                .toArray(Long[]::new);
        List<SysDept> sysDepts = sysDeptService.selectDeptAncestors(array);
        sysDepts.add(dept);
        for (SysDept deptP : sysDepts) {
            //学校
            if ("X".equals(deptP.getDeptType())) {
                orderMap.put("school", deptP.getDeptName());
            }
            //学院
            if ("Y".equals(deptP.getDeptType())) {
                orderMap.put("college", deptP.getDeptName());
            }
            //专业
            if ("Z".equals(deptP.getDeptType())) {
                orderMap.put("major", deptP.getDeptName());
            }
            //班级
            if ("B".equals(dept.getDeptType())) {
                orderMap.put("class", dept.getDeptName());
            }
        }
        //年级
        orderMap.put("grade", order.getGrade());
        // 学号
        orderMap.put("stuNo", order.getStudent().getStuNo());
        //学生姓名
        orderMap.put("studentName", order.getStudent().getStudentName());
        // 缴费项目名称
        orderMap.put("name", order.getOrderName());
        // 总金额
        orderMap.put("amount", order.getTotalPrice());
        //学期
        String semester = order.getSemester();
        if ("C".equals(semester)) {
            semester = "春季";
        } else if ("Q".equals(semester)) {
            semester = "秋季";
        }
        orderMap.put("semester", order.getSemesterYear() + semester);
        if (OrderConstants.PaymentType.UNIQUE.equals(order.getOrderType())) {
            //商品详情
            String orderDetail = order.getOrderDetail();
            List<XcOrdersGoods> xcOrdersGoodsList = JSON.parseArray(orderDetail, XcOrdersGoods.class);
            Map<String, Object> book = new HashMap<>();
            for (XcOrdersGoods good : xcOrdersGoodsList) {
                book.put("id", good.getGoodsId());
                book.put("bookName", good.getGoodsName());
                book.put("price", good.getGoodsPrice());
                book.put("checked", good.getGoodsDetail());
            }
            orderMap.put("book", book);
        }
        //附件
        UfBookList ufBookList = bookListService.selectUfBookListById(order.getOther1());
        String path = configService.selectConfigByKey("sys.resources.path");
        orderMap.put("accessory", path + ufBookList.getBooklistPic());

        //支付记录
        XcPayRecord xcPayRecord = new XcPayRecord();
        xcPayRecord.setOrderId(id);
        List<XcPayRecord> xcPayRecords = payRecordService.selectXcPayRecordList(xcPayRecord);
        orderMap.put("PayRecords", xcPayRecords);

        if (OrderConstants.OrderState.NOTPAY.equals(order.getStatus())) {
            //未支付
            orderMap.put("isPay", false);
        }
        if (OrderConstants.TradeState.SUCCESS.equals(order.getStatus())) {
            //已
            orderMap.put("isPay", true);
        }
        if (OrderConstants.TradeState.REFUND.equals(order.getStatus())) {
            //已退款 也是支付
            orderMap.put("isPay", true);
            List<XcRefundOrder> refundOrders = refundOrderService.selectRefundOrderListByOrderId(order.getId());
            orderMap.put("refunds", refundOrders);
        }

        return success(orderMap);
    }

    /**
     * 订单已支付 -- 支付凭证   -- 与订单详情一致
     */
    @GetMapping(value = "/voucher/{id}")
    public AjaxResult getOderVoucher(@PathVariable("id") String id) {
        Map<String, Object> orderMap = new HashMap<>();
        XcOrders xcOrders = ordersService.selectXcOrdersById(id);
        if (xcOrders == null) {
            throw new ServiceException("订单不存在");
        }
        if (!OrderConstants.TradeState.SUCCESS.equals(xcOrders.getStatus())) {
            throw new ServiceException("订单未支付/已退款");
        }
        // 学校 学院 专业 班级
        SysDept dept = sysDeptService.selectDeptById(Long.valueOf(xcOrders.getDeptId()));
        String ancestors = dept.getAncestors();
        Long[] array = Arrays.stream(ancestors.split(","))
                .map(Long::parseLong)
                .toArray(Long[]::new);
        List<SysDept> sysDepts = sysDeptService.selectDeptAncestors(array);
        sysDepts.add(dept);
        for (SysDept deptP : sysDepts) {
            //学校
            if ("X".equals(deptP.getDeptType())) {
                orderMap.put("school", deptP.getDeptName());
            }
            //学院
            if ("Y".equals(deptP.getDeptType())) {
                orderMap.put("college", deptP.getDeptName());
            }
            //专业
            if ("Z".equals(deptP.getDeptType())) {
                orderMap.put("major", deptP.getDeptName());
            }
            //班级
            if ("B".equals(dept.getDeptType())) {
                orderMap.put("class", dept.getDeptName());
            }
        }
        //年级
        orderMap.put("grade", xcOrders.getGrade());
        // 学号
        orderMap.put("stuNo", xcOrders.getStudent().getStuNo());
        //学生姓名
        orderMap.put("studentName", xcOrders.getStudent().getStudentName());
        // 缴费项目名称
        orderMap.put("name", xcOrders.getOrderName());
        // 总金额
        orderMap.put("amount", xcOrders.getTotalPrice());
        //学期
        String semester = xcOrders.getSemester();
        if ("C".equals(semester)) {
            semester = "春季";
        } else if ("Q".equals(semester)) {
            semester = "秋季";
        }
        orderMap.put("semester", xcOrders.getSemesterYear() + semester);
        //商品详情
//        String orderDetail = xcOrders.getOrderDetail();
//        List<XcOrdersGoods> xcOrdersGoodsList = JSON.parseArray(orderDetail, XcOrdersGoods.class);
//        Map<String, Object> book = new HashMap<>();
//        for (XcOrdersGoods good : xcOrdersGoodsList) {
//            book.put("id", good.getGoodsId());
//            book.put("bookName", good.getGoodsName());
//            book.put("price", good.getGoodsPrice());
//            book.put("checked", good.getGoodsDetail());
//        }
//        orderMap.put("book", book);
        //支付记录 TODO 退款有异常
        XcPayRecord payRecord = payRecordService.selectPayRecordPaySuccessByOrderId(id);
        //商户订单号
        orderMap.put("orderNo", payRecord.getPayNo());
        //本系统支付流水
        orderMap.put("payNo", payRecord.getPayNo());
        //微信订单号
        orderMap.put("wxOrder", payRecord.getOutPayNo());
        String paySuccessTime = payRecord.getPaySuccessTime();//"20240226104515";
        try {
            SimpleDateFormat inputFormat = new SimpleDateFormat("yyyyMMddHHmmss");
            Date date = inputFormat.parse(paySuccessTime);
            SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String formattedStr = outputFormat.format(date);
            orderMap.put("paySuccessTime", formattedStr);
        } catch (ParseException e) {
            orderMap.put("paySuccessTime", paySuccessTime);
        }
        return success(orderMap);
    }

    /**
     * 获取专项缴费的学生，根据缴费项目id 获取关联的班级
     * 根据班级id 获取学生列表
     */
    @PreAuthorize("@ss.hasPermi('uniquefees:bookList:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        try {
            UfBookList ufBookList = bookListService.selectUfBookListById(id);
            Long deptId = ufBookList.getDeptId();
            List<CampusStudents> campusStudents = campusStudentsService.selectCampusStudentsListByDeptId(deptId);
            Map<String, Object> result = new HashMap<>();
            result.put("special",ufBookList);
            result.put("stuList",campusStudents);
            return success(result);
        } catch (Exception e) {
            log.info("更具缴费项目查询学生失败！");
        }
        return success();
    }

    /**
     * 查询订单信息列表
     */
    @PreAuthorize("@ss.hasPermi('order:orders:list')")
    @GetMapping("/{id}/v2")
    public AjaxResult listV2(@PathVariable("id") String id) {
        UfBookList ufBookList = bookListService.selectUfBookListById(id);
        if (ufBookList == null) {
            // 根据业务需求处理 ufBookList 为 null 的情况
            throw new IllegalArgumentException("未找到对应的 UfBookList 记录");
        }
        Long deptId = ufBookList.getDeptId();
        List<CampusStudents> campusStudents = campusStudentsService.selectCampusStudentsListByDeptId(deptId);
        if (campusStudents == null) {
            campusStudents = new ArrayList<>(); // 避免后续遍历空指针
        }

        Map<Long, XcOrdersVO> orderMap = queryOrderMap(id);
        List<StudentOrderVO> studentOrderVos = new ArrayList<>();
        for (CampusStudents stu : campusStudents) {
            StudentOrderVO studentOrderVO = new StudentOrderVO();
            BeanUtils.copyProperties(stu, studentOrderVO);
            // 从 Map 中直接获取订单信息，避免内层循环
            if (stu.getStudentId() != null) {
                XcOrdersVO order = orderMap.get(stu.getStudentId());
                if (order != null) {
                    studentOrderVO.setOrders(order);
                }
            }
            studentOrderVos.add(studentOrderVO);
        }
        Map<String, Object> result = new HashMap<>();
        result.put("special", ufBookList);
        result.put("stuList", studentOrderVos);
        return success(result);
    }

    private Map<Long, XcOrdersVO> queryOrderMap(String id){
        XcOrders xcOrders = new XcOrders();
        xcOrders.setOther1(id);
        List<XcOrders> list = ordersService.selectXcOrdersList(xcOrders);
        // 构建以 studentId 为键的订单映射，提升查找性能
        Map<Long, XcOrdersVO> orderMap = new HashMap<>();
        if (list != null) {
            for (XcOrders orders : list) {
                if (orders.getStudentId() != null) {
                    try {
                        Long studentId = Long.valueOf(orders.getStudentId());
                        XcOrdersVO xcOrdersVO = new XcOrdersVO();
                        BeanUtils.copyProperties(orders,xcOrdersVO);
                        orderMap.put(studentId, xcOrdersVO);
                    } catch (NumberFormatException e) {
                        throw new ServiceException("未找到对应的订单");
                    }
                }
            }
        }
        return orderMap;
    }

    /**
     * 将单位为分的价格格式化为保留两位小数的格式
     * 2299  ->  22.99￥
     */
    public String formatPrice(Long price) {
        double amountInDollars = (double) price / 100.00;
        DecimalFormat decimalFormat = new DecimalFormat("#.00");
        return decimalFormat.format(amountInDollars);
    }

    /**
     * JSAPI 预下单
     */
    @GetMapping("/requestPayment")
    @Log(title = "JSAPI 预下单", businessType = BusinessType.UPDATE)
    public AjaxResult requestPayment(String id) {
        WxUser wxUser = wxUserService.selectWxUserByUserId(getLoginUser().getUserId());
        String openid = wxUser.getOpenId();
        AjaxResult ajaxResult = AjaxResult.error();
        try {
            return ordersService.requestPaymentV2(id, openid);
        } catch (WxPayException e) {

            return ajaxResult;
        }
    }


}
